home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / strategy / vga_card.000 / vga_cardgames-1.3.1.tar / vga_cardgames / solitaire.c < prev    next >
C/C++ Source or Header  |  1994-04-25  |  5KB  |  266 lines

  1. /*
  2.  * Solitaire game (name unknown)
  3.  *
  4.  * Copyright (C) Evan Harris, 1991, 1994
  5.  *
  6.  * Permission is granted to freely redistribute and modify this code,
  7.  * providing the author(s) get credit for having written it.
  8.  */
  9.  
  10. #include "solitaire.h"
  11. #include <stdlib.h>
  12.  
  13.  
  14. #define U_MOVE            1
  15. #define U_MOVE_EXPOSE        3
  16.  
  17. struct undo {
  18.     unsigned char    type;
  19.     unsigned char    card;
  20.     short        from;
  21.     struct undo    *next;
  22. };
  23.  
  24.  
  25. unsigned char    column[COLUMNS];        /* First card of column */
  26. short        cards[NUMCARDS];        /* Positions of cards */
  27. unsigned char    next[NUMCARDS];            /* Card underneath */
  28. unsigned char    hidden[NUMCARDS];        /* Cards which are face down */
  29. struct undo    *undoinfo = NULL;
  30.  
  31.  
  32. void main(int argc, char **argv)
  33. {
  34.     short cmd, dest;
  35.  
  36.     InitDisplay(argc, argv);
  37.  
  38.     InitRandom(NEW);
  39.     Deal();
  40.  
  41.     for (;;) {
  42.     cmd = GetCmd();
  43.     if (cmd == QUIT) {
  44.         EndDisplay();
  45.         exit(0);
  46.     }
  47.     if (cmd == NEWGAME) {
  48.         InitRandom(NEW);
  49.         Deal();
  50.     }
  51.     else if (cmd == RESTART) {
  52.         InitRandom(LAST);
  53.         Deal();
  54.     }
  55.     else if (cmd == UNDO) {
  56.         Undo();
  57.     }
  58.     else if (ISCARD(cmd)) {
  59.         dest = FindDest((unsigned char)cmd);
  60.         if (dest != NOPOSN)
  61.         MakeMove((unsigned char)cmd, dest);
  62.     }
  63.     }
  64.  
  65.     /* Never reached */
  66. }
  67.  
  68.  
  69. void Deal()
  70. {
  71.     unsigned char i, j;
  72.     short r;
  73.  
  74.     /* Initialise the deck */
  75.     for (i = 0; i < NUMCARDS; i++) {
  76.     cards[i] = NOPOSN;
  77.     next[i] = NOCARD;
  78.     }
  79.         
  80.     /* Deal the deck */
  81.     for (i = 0; i < NUMCARDS; i++) {
  82.     r = Random(NUMCARDS - i);
  83.     for (j = 0; j < NUMCARDS && r >= 0; j++) {
  84.         if (cards[j] == NOPOSN)
  85.         r--;
  86.     }
  87.     r = j - 1;
  88.  
  89.     cards[r] = POSN(i % 7, i / 7);
  90.     if (i / 7 == 0)
  91.         column[i % 7] = r;
  92.     else {
  93.         for (j = 0; cards[j] != POSN(i % 7, i / 7 - 1); j++)
  94.         ;
  95.         next[j] = r;
  96.     }
  97.     if ((i / 7 <= 2) && (i % 7 >= 4))
  98.         hidden[r] = 1;
  99.     else
  100.         hidden[r] = 0;
  101.     }
  102.  
  103.     for (i = 0; i < 7; i++)
  104.     DisplayColumn((short)i);
  105.  
  106.     return;
  107. }
  108.  
  109.  
  110. short FindDest(unsigned char card)
  111. {
  112.     unsigned char i, c;
  113.  
  114.     if (TYPE(card) == KING) {
  115.     if (ROW(cards[card]) == 0)
  116.         return NOPOSN;
  117.     for (i = 0; i < COLUMNS; i++)
  118.         if (column[i] == NOCARD)
  119.         return (short)POSN(i, 0);
  120.     }
  121.     else {
  122.     for (i = 0; i < COLUMNS; i++)
  123.         if (i != COL(cards[card])) {
  124.         c = column[i];
  125.         while (next[c] != NOCARD)
  126.             c = next[c];
  127.         if (c == CARD(SUIT(card), TYPE(card) + 1))
  128.             return (short)POSN(COL(cards[c]), ROW(cards[c]) + 1);
  129.         }
  130.     }
  131.  
  132.     return NOPOSN;
  133. }
  134.  
  135.  
  136. void MakeMove(unsigned char card, short dest)
  137. {
  138.     short col, row, oldcol;
  139.     unsigned char c, i;
  140.     unsigned char h = 0;
  141.  
  142.     col = COL(dest);
  143.     row = ROW(dest);
  144.     oldcol = -1;
  145.  
  146.     for (i = 0; oldcol == -1 && i < COLUMNS; i++) {
  147.     if (column[i] == card) {
  148.         column[i] = NOCARD;
  149.         oldcol = i;
  150.     }
  151.     }
  152.     for (i = 0; oldcol == -1 && i < NUMCARDS; i++) {
  153.     if (next[i] == card) {
  154.         if (hidden[i]) {
  155.         hidden[i] = 0;
  156.         h = 1;
  157.         }
  158.         next[i] = NOCARD;
  159.         oldcol = COL(cards[i]);
  160.     }
  161.     }
  162.     if (h)
  163.     AddUndo(U_MOVE_EXPOSE, card, cards[card]);
  164.     else
  165.     AddUndo(U_MOVE, card, cards[card]);
  166.  
  167.     if (row > 0) {
  168.     c = column[col];
  169.     while (next[c] != NOCARD)
  170.         c = next[c];
  171.     next[c] = card;
  172.     }
  173.     else
  174.     column[col] = card;
  175.     while (card != NOCARD) {
  176.     cards[card] = POSN(col, row++);
  177.     card = next[card];
  178.     }
  179.  
  180.     DisplayColumn(oldcol);
  181.     DisplayColumn(col);
  182.  
  183.     return;
  184. }
  185.  
  186.  
  187. void AddUndo(unsigned char type, unsigned char card, short from)
  188. {
  189.     struct undo *undo;
  190.  
  191.     undo = (struct undo *)malloc(sizeof(struct undo));
  192.     undo->type = type;
  193.     undo->card = card;
  194.     undo->from = from;
  195.     undo->next = undoinfo;
  196.     undoinfo = undo;
  197.  
  198.     return;
  199. }
  200.  
  201.  
  202. void Undo()
  203. {
  204.     struct undo *undo = undoinfo;
  205.  
  206.     if (undo == NULL)
  207.     return;
  208.  
  209.     switch (undo->type) {
  210.       case U_MOVE:
  211.     UndoMove(undo->card, (short)COL(undo->from), 0);
  212.     break;
  213.       case U_MOVE_EXPOSE:
  214.     UndoMove(undo->card, (short)COL(undo->from), 1);
  215.     break;
  216.     }
  217.  
  218.     undoinfo = undoinfo->next;
  219.     free(undo);
  220.  
  221.     return;
  222. }
  223.  
  224.  
  225. void UndoMove(unsigned char card, short col, unsigned char expose)
  226. {
  227.     unsigned char c, row;
  228.     short oldcol;
  229.  
  230.     oldcol = COL(cards[card]);
  231.     c = column[oldcol];
  232.     if (c == card) {
  233.     column[oldcol] = NOCARD;
  234.     } else {
  235.     while (next[c] != card)
  236.         c = next[c];
  237.     next[c] = NOCARD;
  238.     }
  239.  
  240.     c = column[col];
  241.     row = 0;
  242.     if (c == NOCARD) {
  243.     column[col] = card;
  244.     cards[card] = POSN(col, row);
  245.     c = next[card];
  246.     } else {
  247.     while (next[c] != NOCARD) {
  248.         c = next[c];
  249.         row++;
  250.     }
  251.     if (expose)
  252.         hidden[c] = 1;
  253.     next[c] = card;
  254.     cards[card] = POSN(col, ++row);
  255.     c = next[card];
  256.     }
  257.     while (c != NOCARD) {
  258.     cards[c] = POSN(col, ++row);
  259.     c = next[c];
  260.     }
  261.     DisplayColumn(oldcol);
  262.     DisplayColumn(col);
  263.  
  264.     return;
  265. }
  266.